/**
* @file idt.h
* Interrupt Description table interface for X86 platform.
* Contains data structures and function for IDT managment:
* to define new interrupt, generate interrupt, set location of IDT to processor,
* interrupt callback etc...
*
* Copyrights 2010 Michal Saman, m.saman@designplus.cz.
* This source code is release under the Apache License 2.0.
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef _IDT_H
#define _IDT_H

#ifndef ARCH_X86
#error "[idt.h] is platform-independent. Define ARCH_X86."
#endif

#include <stdint.h>

/** define 256 max. interrupts handlers. */
#define IDT_MAX_INTERRUPTS	256 

#define IDT_DESC_BIT16		0x06	// 00000110
#define IDT_DESC_BIT32		0x0E	// 00001110
#define IDT_DESC_RING1		0x40	// 01000000
#define IDT_DESC_RING2		0x20	// 00100000
#define IDT_DESC_RING3		0x60	// 01100000
#define IDT_DESC_PRESENT	0x80	// 10000000

/**
* Data type for IR handler function.
* IR handlers are called by the processor. Stack status may change, so leave it on 
* called function implementation to handle it and properly return.
*/
typedef void (* IRQ_HANDLER)(void) __attribute__ ((cdecl));

//#pragma pack(push, 1)
/**
* Data structure for one interrupt descriptor.
*/
struct IdtDescriptor {
	uint16_t	baseLo;				/**< low part of memory address of interrupt routine (handler) / bit 0-15 */
	uint16_t	code_selector;		/**< code selector in GDT */
	uint8_t		reserved;			/**< reserved area by INTEL gurus :) */
	uint8_t		flags;				/**< Bit flags for this descriptor */
	uint16_t	baseHi;				/**< high part of memory address of interrupt routine (handler) / bit 16-32 */
};
//#pragma pack(pop)

extern struct IdtDescriptor * idt_get_descriptor(uint32_t);
extern int idt_set_descriptor(uint32_t i, uint16_t flags, uint16_t code_selector, IRQ_HANDLER);
extern int idt_init(uint16_t code_selector);

#endif
